package com.doordu.soa.service.web.service;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang3.StringUtils;

import com.alibaba.fastjson.JSONObject;
import com.doordu.soa.service.comm.ResultData;
import com.doordu.soa.service.comm.utils.DateUtils;
import com.doordu.soa.service.web.annotation.DataValid;
import com.doordu.soa.service.web.em.RegexType;
import com.doordu.soa.service.web.fieldvalidator.ValidatorFactory;
import com.doordu.soa.service.web.utils.RegexUtils;

/**
 * Created by marvin on 2017/2/15.
 */
public class DataValidService {

	private static DataValid dataValid;

	public static void setReturnData(String flag,ResultData<Object> resultData,String msg) {
		Map<String, String> map = new HashedMap<>();
		map.put("flag", flag);
		resultData.setDesc(msg);
		resultData.setMsg(msg);
		resultData.setData(map);
	}

	public DataValidService() {
		super();
	}

	public static String checkData(Object object) {
		String result = null;
		try {
			if (object.getClass().isPrimitive()) {
				return null;
			}

			if (List.class.isAssignableFrom(object.getClass())) {
				for (Object args : (List) object) {
					DataValidService.valid(args);
				}
			} else {
				DataValidService.valid(object);
			}
		} catch (Exception e) {
			if (StringUtils.isNotBlank(e.getMessage())) {// 放开在方法中可空的参数cameraBrandList(String
															// brandName）
				result = "参数校验失败：" + e.getMessage();
			}
		}
		return result;
	}

	// 解析的入口
	public static void valid(Object object) throws Exception {
		// 获取object的类型
		Class<? extends Object> clazz = object.getClass();
		// 获取该类型声明的成员
		Field[] fields = clazz.getDeclaredFields();
		// 遍历属性
		for (Field field : fields) {
			// 对于private私有化的成员变量，通过setAccessible来修改器访问权限
			field.setAccessible(true);
			validate(field, object);
			// 重新设置会私有权限
			field.setAccessible(false);
		}
	}

	public static void validate(Field field, Object object) throws Exception {

		String description;
		Object value;

		// 获取对象的成员的注解信息
		dataValid = field.getAnnotation(DataValid.class);
		value = field.get(object);

		if (dataValid == null)
			return;

		description = dataValid.description().equals("") ? field.getName() : dataValid.description();

		/************* 注解解析工作开始 ******************/
		if (!dataValid.nullable()) {
			if (value == null || StringUtils.isBlank(value.toString())) {
				throw new Exception(description + "不能为空");
			}
			if (value.toString().length() > dataValid.maxLength() && dataValid.maxLength() != 0) {
				throw new Exception(description + "长度不能超过" + dataValid.maxLength());
			}

			if (value.toString().length() < dataValid.minLength() && dataValid.minLength() != 0) {
				throw new Exception(description + "长度不能小于" + dataValid.minLength());
			}
		} else if (dataValid.nullable()) {// 可空，有值时先判断长度
			if (value != null && !StringUtils.isBlank(value.toString())) {
				if (value.toString().length() > dataValid.maxLength() && dataValid.maxLength() != 0) {
					throw new Exception(description + "长度不能超过" + dataValid.maxLength());
				}

				if (value.toString().length() < dataValid.minLength() && dataValid.minLength() != 0) {
					throw new Exception(description + "长度不能小于" + dataValid.minLength());
				}
			}
		}

		String checkmsg = ValidatorFactory.checkField(dataValid, object, value);
		if (StringUtils.isNotEmpty(checkmsg)) {
			throw new Exception(String.format("%s%s", description, checkmsg));
		}

		boolean nullFlag = dataValid.nullable();
		if (dataValid.regexType() != RegexType.NONE) {
			switch (dataValid.regexType()) {
			case NONE:
				break;
			case NO_SPECIALCHAR:
				if (!nullFlag && RegexUtils.hasSpecialChar(value.toString())) {
					throw new Exception(description + "不能含有特殊字符");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {// 非必填且不为空
					if (RegexUtils.hasSpecialChar(value.toString())) {
						throw new Exception(description + "不能含有特殊字符");
					}
				}
				break;
			case IS_GUID:
				if (!nullFlag && !RegexUtils.isGuid(value.toString())) {
					throw new Exception(description + "不能含有特殊字符");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isGuid(value.toString())) {
						throw new Exception(description + "不能含有特殊字符");
					}
				}
				break;
			case IS_JSON:
				if (!nullFlag && !RegexUtils.isJson(value)) {
					throw new Exception(description + "不是JSON格式");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isJson(value)) {
						throw new Exception(description + "不是JSON格式");
					}
				}
				break;
			case PASSWORD18:
				if (!nullFlag && !RegexUtils.isPassword18(value.toString())) {
					throw new Exception(description + "密码必须6-18位的字母和数字");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isPassword18(value.toString())) {
						throw new Exception(description + "密码必须6-18位的字母和数字");
					}
				}
				break;
			case CHINESE:
				if (!nullFlag && !RegexUtils.isChinese2(value.toString())) {
					throw new Exception(description + "不是中文字符");
				}
				break;
			case EMAIL:
				if (!nullFlag && !RegexUtils.isEmail(value.toString())) {
					throw new Exception(description + "地址格式不正确");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isEmail(value.toString())) {
						throw new Exception(description + "地址格式不正确");
					}
				}
				break;
			case IP:
				if (!nullFlag && !RegexUtils.isIp(value.toString())) {
					throw new Exception(description + "地址格式不正确");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isIp(value.toString())) {
						throw new Exception(description + "地址格式不正确");
					}
				}
				break;
			case DATE_YYYY_MM_DD:
				if (!nullFlag && !RegexUtils.isDateForYyyyMmDd(value.toString())) {
					if (!DateUtils.isValidDate(value.toString())) {
						throw new Exception(description + "格式不正确");
					}
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isDateForYyyyMmDd(value.toString()) || !DateUtils.isValidDate(value.toString())) {
						throw new Exception(description + "格式不正确");
					}
				}
				break;
			case DATE_YYYY_MM_DD_HH_MM_SS:
				if (!nullFlag && !DateUtils.isValidDate2(value.toString())) {
					throw new Exception(description + "格式不正确");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!DateUtils.isValidDate(value.toString())) {
						throw new Exception(description + "格式不正确");
					}
				}
				break;
			case DATE_YYYYMMDDHHMMSS:
				if (!nullFlag && !DateUtils.isValidDateYYYYMMDDHHMMSS(value.toString())) {
					throw new Exception(description + "格式不正确");
				} 
				break;
			case ID:
				if (!nullFlag && !RegexUtils.isIdcard(value.toString())) {
					throw new Exception(description + "格式不正确");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isIdcard(value.toString())) {
						throw new Exception(description + "格式不正确");
					}
				}
				break;
			case NUMBER:
				if (!nullFlag && !RegexUtils.isNumber(value.toString())) {
					throw new Exception(description + "不是数字");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isNumber(value.toString())) {
						throw new Exception(description + "不是数字");
					}
				}
				break;
			case DECIMAL:
				if (null != value) {
					try {
						Double.valueOf(value.toString());
					} catch (Exception e) {
						throw new Exception(description + "不是小数");
					}
				}
				break;
			case MOBILE:
				if (!nullFlag && !RegexUtils.isMobile(value.toString())) {
					throw new Exception(description + "格式不正确");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isMobile(value.toString())) {
						throw new Exception(description + "格式不正确");
					}
				}
				break;
			case ALL_MOBILE:
				if (!nullFlag && !RegexUtils.isAllMobile(value.toString())) {
					throw new Exception(description + "格式不正确");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isAllMobile(value.toString())) {
						throw new Exception(description + "格式不正确");
					}
				}
				break;
			case MOBILE_TEL:
				if (!nullFlag && !RegexUtils.isMoibleOrTelePhone(value.toString())) {
					throw new Exception(description + "格式不正确");
				} else if (nullFlag && RegexUtils.isNotNull(value)) {
					if (!RegexUtils.isMoibleOrTelePhone(value.toString())) {
						throw new Exception(description + "格式不正确");
					}
				}
				break;
			default:
				break;
			}
		}

		if (!dataValid.regexExpression().equals("")) {
			if (value.toString().matches(dataValid.regexExpression())) {
				throw new Exception(description + "格式不正确");
			}
		}
		/************* 注解解析工作结束 ******************/
	}
}
